package fr.chrysalis.ui.components.core
{	
	import com.greensock.TweenMax;
	
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	
	import fr.chrysalis.ui.UI;
	import fr.chrysalis.ui.assets.Asset;
	import fr.chrysalis.ui.assets.IAsset;
	import fr.chrysalis.ui.assets.SWFAsset;
	import fr.chrysalis.ui.components.display.ScrollBar;
	import fr.chrysalis.ui.components.display.ScrollBarMode;
	import fr.chrysalis.ui.components.events.ComponentEvent;
	import fr.chrysalis.ui.components.events.ScrollBarEvent;
	import fr.chrysalis.ui.components.interfaces.IComponent;
	import fr.chrysalis.utils.Debug;
	
	public class ContainerScrollable extends Container implements IComponent
	{
		
		/**
		 * Reference vers le container
		 */
		public var content:Container;
		
		/**
		 * Mask de contenu 
		 */
		private var dynamicMask:MovieClip;
		
		/**
		 * Scrollbar verticale
		 */
		public var scrollBarY:ScrollBar;
		
		/**
		 * Scrollbar horizontale
		 */
		public var scrollBarX:ScrollBar;
		
		/**
		 * Largeur du composant 
		 */
		override public function get width():int
		{
			return this.size.width;
		}
		
		/**
		 * Hauteur du composant 
		 */
		override public function get height():int
		{
			return this.size.height;
		}
		
		public function ContainerScrollable(asset:IAsset)
		{
			this.dynamicMask = new MovieClip();
			
			this.scrollBarX = new ScrollBar( new SWFAsset(UI.get('scrollbar')) );
			this.scrollBarX.addEventListener(ScrollBarEvent.MOVE, handlerScrollBarXMove);
			this.scrollBarX.get().alpha = 0;
			
			this.scrollBarY = new ScrollBar( new SWFAsset(UI.get('scrollbar')) );
			this.scrollBarY.mode = ScrollBarMode.VERTICAL;
			this.scrollBarY.addEventListener(ScrollBarEvent.MOVE, handlerScrollBarYMove);
			this.scrollBarY.get().alpha = 0;
			
			this.content = new Container(new Asset());
			this.content.parent = this;
			
			super(asset);
			
			this.element.addChild(this.content.get());
			
			this.container.addChild(this.scrollBarX.get());
			this.container.addChild(this.scrollBarY.get());
			this.container.addChild(this.dynamicMask);
			this.element.mask = this.dynamicMask;
			
			this.container.addEventListener(MouseEvent.ROLL_OVER, handlerRollOver);
		}
		
		/**
		 * Ajoute le contenu
		 * @param component Container à ajouter
		 */
		override public function addChild(component:Component):void{
			this.content.addChild(component);
			component.parent = this.content;
			this.content.addEventListener(ComponentEvent.UPDATE, handlerContentUpdate);
			this.update();
		}
		
		/**
		 * Supprime le container
		 */
		override public function removeChild(component:Component):void{
			this.content.removeChild(component);
			this.content.addEventListener(ComponentEvent.UPDATE, handlerContentUpdate);
			this.update();
		}
		
		/**
		 * Met a jour le mask 
		 */
		override public function update():void{
			super.update();
			this.dynamicMask.graphics.clear();
			this.dynamicMask.graphics.beginFill( 0xFFFFFF, 1 );
			this.dynamicMask.graphics.drawRect( 0, 0, this.width, this.height );
			this.dynamicMask.graphics.endFill();
			
			this.scrollBarY.x = this.width - 2;
			this.scrollBarY.y = 2;
			this.scrollBarY.limit = this.height - this.scrollBarY.y*2;
			
			this.scrollBarX.x = 2;
			this.scrollBarX.y = this.height - this.scrollBarX.height - this.scrollBarX.x;
			this.scrollBarX.limit = this.width - this.scrollBarX.x*2;
			
			var sizeHeight:int = (this.height * this.height) / this.content.height;
			var sizeWidth:int = (this.width * this.width) / this.content.width;
			
			this.scrollBarX.updateSize(sizeWidth);
			this.scrollBarY.updateSize(sizeHeight);
		}
		
		/**
		 * Handler lorsque que la scrollbar horizontal bouge  
		 */
		protected function handlerScrollBarXMove(evt:ScrollBarEvent):void{
			this.updateContent();
		}
		
		/**
		 * Handler lorsque que la scrollbar vertical bouge  
		 */
		protected function handlerScrollBarYMove(evt:ScrollBarEvent):void{
			this.updateContent();
		}
		
		/**
		 * Handler lorsque que le contenu est update
		 */
		protected function handlerContentUpdate(evt:ComponentEvent):void{
			this.updateContent();
		}
		
		/**
		 * Handler lorsque que la souris rentre dans le container 
		 */
		protected function handlerRollOver(evt:MouseEvent):void{
			this.container.removeEventListener(MouseEvent.ROLL_OVER, handlerRollOver);
			this.container.addEventListener(MouseEvent.ROLL_OUT, handlerRollOut);
			this.container.addEventListener(MouseEvent.MOUSE_WHEEL, handlerMouseWheel);
			this.showScrollBar();
		}
		
		/**
		 * Handler lorsque que la souris sort du container 
		 */
		protected function handlerRollOut(evt:MouseEvent):void{
			this.container.addEventListener(MouseEvent.ROLL_OVER, handlerRollOver);
			this.container.removeEventListener(MouseEvent.ROLL_OUT, handlerRollOut);
			this.container.removeEventListener(MouseEvent.MOUSE_WHEEL, handlerMouseWheel);
			this.hideScrollBar();
		}
		
		/**
		 * Handler lorsque que la molette tourne
		 */
		protected function handlerMouseWheel(evt:MouseEvent):void{
			
			var scrollBar:ScrollBar;
			var offset:int = 10;
			var interval:int = this.content.height-this.height;
			
			if(evt.ctrlKey){
				scrollBar = this.scrollBarX;
				interval = this.content.width-this.width;
			}else{
				scrollBar = this.scrollBarY;
				interval = this.content.height-this.height;
			}
			
			if(interval < 50){
				offset = 100;
			}
			if(interval >= 50 && interval <= 500){
				offset = 100 - int(Math.log( ((100 * interval) / 550)/10 )* 0.434294481904 * 100);
			}
			
			if(evt.delta > 0 ){
				scrollBar.scroll(scrollBar.pourcent - offset);
			}else{
				scrollBar.scroll(scrollBar.pourcent + offset);
			}
		}
		
		/**
		 * Affiche les scrollbars
		 */
		protected function showScrollBar():void{
			if(this.content.width > this.width){
				TweenMax.to(this.scrollBarX.get(), 0.5, {alpha:1, useFrames: false});
			}
			if(this.content.height > this.height){
				TweenMax.to(this.scrollBarY.get(), 0.5, {alpha:1, useFrames: false});
			}
		}
		
		/**
		 * Cache les scrollbars
		 */
		protected function hideScrollBar():void{
			TweenMax.to(this.scrollBarX.get(), 0.5, {alpha:0, useFrames: false});
			TweenMax.to(this.scrollBarY.get(), 0.5, {alpha:0, useFrames: false});
		}
		
		/**
		 * Met à jour le contenu en fonction des scrollbars  
		 */
		public function updateContent():void{
			var x:int = -(this.scrollBarX.pourcent/100) * (this.content.width-this.width);
			var y:int = -(this.scrollBarY.pourcent/100) * (this.content.height-this.height);
			
			if(x != this.content.x || y != this.content.y){
				TweenMax.to(this.content.get(), 0.2, {x:x, y:y, useFrames: false});
			}
		}
		
	}
}